package com.grsu.phonestation.dao.impl;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.grsu.phonestation.dao.UserActiveDAO;
import com.grsu.phonestation.dao.impl.base.AbstractHibernateDAO;
import com.grsu.phonestation.domain.Client;
import com.grsu.phonestation.domain.Dialogue;
import com.grsu.phonestation.domain.InternetService;
import com.grsu.phonestation.domain.PhoneService;
import com.grsu.phonestation.domain.Session;
import com.grsu.phonestation.domain.UserActive;

@Repository
public class UserActiveDAOImpl<UA extends UserActive> extends
		AbstractHibernateDAO<UA, Integer> implements UserActiveDAO<UA> {

	@SuppressWarnings("unchecked")
	protected Class<UA> getGenericEntityClass() {
		return (Class<UA>) UserActive.class;
	}

	@SuppressWarnings("unchecked")
	@Override
	public UA findById(Integer userActiveId) {
		Criteria criteria = getSession().createCriteria(
				this.getGenericEntityClass(), "userActive").add(
				Restrictions.eq("id", userActiveId));
		return (UA) criteria.uniqueResult();
	}

	@SuppressWarnings("unchecked")
	public List<UA> listActiveClientForPeriod(String user, String beginPeriod,
			String endPeriod) {
		Criteria criteria = getSession().createCriteria(
				this.getGenericEntityClass(), "userActive");

		if (user != null && !user.isEmpty()) {
			criteria.createAlias("userActive.user", "user");
			criteria.add(Restrictions.or(Restrictions.like("user.firstname",
					user, MatchMode.ANYWHERE), Restrictions.like(
					"user.lastname", user, MatchMode.ANYWHERE)));
		}
		if (beginPeriod != null) {
			criteria.add(Restrictions.ge("userActive.dateActivation",
					beginPeriod));
		}

		if (endPeriod != null) {
			criteria.add(Restrictions.lt("userActive.dateActivation",
					endPeriod));
		}

		List<UA> list = criteria.list();

		List<UA> result = new ArrayList<UA>();

		if (list != null && !list.isEmpty()) {
			result.addAll(list);
		}

		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<UA> getUnReplayActiveClient(Client client) {
		Criteria criteria = getSession().createCriteria(
				this.getGenericEntityClass(), "userActive");
		if (client != null) {
			criteria.add(Restrictions.eq("userActive.user", client));
			criteria.add(Restrictions.eq("userActive.isReplay", false));
		}

		List<UA> list = criteria.list();

		List<UA> result = new ArrayList<UA>();

		if (list != null && !list.isEmpty()) {
			result.addAll(list);
		}

		return result;
	}

	@Override
	public double getSumUnReplayActiveClient(Client client) {

		double sum = 0;

		List<UA> activesObjects = getUnReplayActiveClient(client);
		for (UA activesObject : activesObjects) {
			if (activesObject instanceof Session) {
				Session active = (Session) activesObject;
				if (active.getService() instanceof PhoneService) {
					PhoneService service = (PhoneService) active.getService();
					double price = active.getSpentTraffic()
							* service.getPrice();
					sum = sum + price;
				}
				if (active.getService() instanceof InternetService) {
					InternetService service = (InternetService) active
							.getService();
					double price = active.getSpentTraffic()
							* service.getPrice();
					sum = sum + price;
				}

			} else {
				Dialogue active = (Dialogue) activesObject;
				if (active.getService() instanceof PhoneService) {
					PhoneService service = (PhoneService) active.getService();
					double price = active.getDuration() * service.getPrice();
					sum = sum + price;
				}
				if (active.getService() instanceof InternetService) {
					InternetService service = (InternetService) active
							.getService();
					double price = active.getDuration() * service.getPrice();
					sum = sum + price;
				}
				
			}
			activesObject.setIsReplay(true);
			update(activesObject);

		}
		return sum;

	}

	@Override
	@SuppressWarnings("unchecked")
	public List<Client> getClientsHaveUnReplayActive() {
		Criteria criteria = getSession().createCriteria(
				getGenericEntityClass(), "userActive");
		criteria.add(Restrictions.eq("isReplay", false));
		criteria.setProjection(Projections.distinct(Projections.property("userActive.user")));
		
		List<Client> list = criteria.list();

		List<Client> result = new ArrayList<Client>();

		if (list != null && !list.isEmpty()) {
			result.addAll(list);
		}

		return result;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<UA> getUserActiveClient(Client client) {
		Criteria criteria = getSession().createCriteria(getGenericEntityClass());
		criteria.add(Restrictions.eq("user", client));
		List<UA> list = criteria.list();

		List<UA> result = new ArrayList<UA>();

		if (list != null && !list.isEmpty()) {
			result.addAll(list);
		}

		return result;
	}

}
